#include "reader.h"
#include "psam_card.h"
#include "cpu_card.h"
#include "mifare_card.h"
#include "quick_pass_card.h"
#include "rc500.h"

platform_data platform;
s32 	  DEBUG_APP_WALL	 =  __DEBUG_APP_O0__ ; // 默认打印信息


/**
  * 功能:  获取离散因子
  * 
  *
  * 返回值:
  * 	   
  **/

s32 reader_get_factor(reader_op *reader)
{
	s32 ret = 0;
	card_data send;

	if (!reader) {
		debug("reader_get_factor: para error!!!\n");
		return RET_ERR;
	}

	switch (reader->card_type) {
		case NORMAL_CPU_CARD: // 从指定路径读取序列号
			send.type	 = READER_CONTACTLESS_CPU;
			send.cla	 = 0x00;
			send.cmd.ins = APDU_READ_BINARY;
			send.pa1.p1  = 0x95;
			send.pa2.p2  = 0x0a;
			send.len.lc  = 0;
			send.le 	 = 18;
			reader_communication(reader, &send);
			if ((send.sw1 << 8 | send.sw2) != 0x9000) {
				debug("reader_get_factor: select cpu %s file failed\n", CPU_CARD_FILE_NAME);
				return RET_ERR;
			}

			memcpy(reader->card_num, send.data, 8);
			break;
			
		case NORMAL_M1_CARD:
			if (SECRTOR_KEY_FACTOR_ASN == platform.factor) {
				if (platform.type == CHINA_UNICOM) {
					memcpy(reader->key_data, CUCC_YKT_MIFARE_KEY, strlen(CUCC_YKT_MIFARE_KEY));
					reader->key_len = strlen(CUCC_YKT_MIFARE_KEY);
					ret = mifare_card_check_key(reader, S0B3, MIFARE_KA);
				}
				else if (platform.type == CHINA_TELECOM) {
					memcpy(reader->key_data, CTCC_YJD_MIFARE_KAY, strlen(CTCC_YJD_MIFARE_KAY));
					reader->key_len = strlen(CTCC_YJD_MIFARE_KAY);
					ret = mifare_card_check_key(reader, S0B3, MIFARE_KA);
				}
				else {
					return RET_ERR;
				}
				

				ret = mifare_card_read_block(reader, &send, S0B1);
				if (ret <= 0) {
					debug("reader_get_factor: read block failed!!!\n");
					return RET_ERR;
				}
				else {
					memcpy(reader->card_num, &send.data[4], 8);
				}
			}
			else if (SECRTOR_KEY_FACTOR_UID == platform.factor) {
				reader->card_num[4] = reader->card_num[0];
				reader->card_num[5] = reader->card_num[1];
				reader->card_num[6] = reader->card_num[2];
				reader->card_num[7] = reader->card_num[3];
			}
			else {
				debug("reader_get_factor: factor flag para error!!!\n");
				return RET_ERR;
			}
			break;

		default:
			debug("reader_get_factor: type error!!!\n");
			return RET_ERR;
	}


	if (DEBUG_APP_WALL > __DEBUG_APP_O1__) {
		int i = 0;
		debug("reader_get_factor: ");
		for (i=0; i<8; i++) {
			debug("%02X", reader->card_num[i]);
		}
		debug("\n");
	}
	
	return RET_OK;
}



/**
  * 功能:  读头退出
  * 
  *
  * 返回值:
  * 	   
  **/

static s32 reader_exit(void *op) // 测试不能退出卡交易
{
	s32 ret = 0;
	reader_op * reader = (reader_op *)op;
	card_data send;
	
	if (!op) {
		debug("psam_apdu_exit: para error!!!\n");
		return RET_ERR;
	}

	memset(send.data, 0, READER_BUF_SIZ);
	send.type			= READER_SETTING;
	send.cmd.mf_comm	= RC500_HALT_CARD;
	send.pa1.mf_flag	= 0x00; 
	send.pa2.mf_sector	= 0x00;
	send.len.mf_len 	= 0x00;
	ret = reader_communication(reader, &send);
	if (ret) {
		return RET_ERR;
	}

	if (DEBUG_APP_WALL > __DEBUG_APP_O1__) {
		debug("DEBUG_info: reader exit done\n");
	}
	return RET_OK;
}



/**
 * 功能:  搜索卡
 * 
 *
 * 返回值:
 *        
 **/
static s32 reader_search(void *op)
{
	s32 ret = -1;
	reader_op *reader = (reader_op *)op;

	if (!reader) {
		debug("reader_find_card_handle: para error!!!\n");
		return RET_ERR;
	}

	/* 寻卡成功card_id存有寻到卡片的物理ID */
	if (reader->card_stat == FIND_CARD_FAIL) {
		switch (platform.mode) {
			case RC500_MODE:
				ret = rc500_find_card_handle(reader);
				break;
				
			case X24_MODE:
				break;

			case DOUBLE_MODE:
				ret = rc500_find_card_handle(reader);
				break;

			default:
				break;
		}
	}

	return (ret==RET_OK)?FIND_CARD_SUCC:FIND_CARD_FAIL;
}



/**
 * 功能:  关闭读头
 * 
 *
 * 返回值:
 *        
 **/
static s32 reader_close(reader_op *reader)
{
#if (SYSTEM == LINUX)
	if (reader->fd[0] > 0) {
		close(reader->fd[0]);
		reader->fd[0] = 0;
		
		return RET_OK;
	}
	else {
		debug("read_close: pare error!!!\n");
		return RET_ERR;
	}
#endif
}


/**
 * 功能:  初始化读头
 * 
 *
 * 返回值:
 *        读头句柄(返回NULL，并填写errno)
 **/
reader_op* reader_attr_create(platform_data *data)
{
	s32 ret = 0;
	reader_op *reader = NULL;

	if (!data) {
		debug("reader_attr_create: para error\n");
		my_errno_set(PARA_ERR);
		return NULL;
	}


	reader = (reader_op *)malloc(sizeof(reader_op));
	if (!reader) {
		debug("reader_attr_init: malloc failed!!!\n");
		my_errno_set(MALLOC_ERR);
		return NULL;
	}
	
	// 初始化数据
	memset(reader, 0, sizeof(reader_op));
	reader->card_type       = READER_CONTACTLESS_M1;
	reader->find_op			= reader_search;
	reader->exit_op         = reader_exit;
	reader->card_stat       = FIND_CARD_FAIL;

	memcpy(&platform, data, sizeof(platform_data));

	//初始化读头
	ret = rc500_init(reader);
	if (ret < 0) {
		free(reader);
		my_errno_set(RC500_INIT_ERR);
		return NULL;
	}

	//保存平台数据
	if (platform.psam == PSAM_MODE) {
	    ret = psam_card_init(reader); // 选择PSAM文件
		if (ret) {
			free(reader);
			my_errno_set(PSAM_INIT_ERR);
			return NULL;
		}
	}
	else {
		memcpy(reader->terminal, platform.terminal, sizeof(platform.terminal));
		memcpy(reader->kkey, platform.kkey, sizeof(platform.kkey));
	}

	if (DEBUG_APP_WALL > __DEBUG_APP_O0__) {
		debug("DEBUG_info: reader init done\n");
	}

	my_errno_set(NO_ERR);
	return reader;
}


/**
 * 功能:  注销读头
 * 
 *
 * 返回值:
 *        
 **/
s32 reader_attr_destroy(reader_op *reader)
{
	if (!reader) {
		debug("reader_attr_destroy: para error!!!\n");
		return RET_ERR;
	}

	reader_close(reader);
	free(reader);
	reader = NULL;
	return RET_OK;
}


/**
 * 功能:  读头通信
 * 
 *
 * 返回值:
 *        
 **/
s32 reader_communication(reader_op *reader, card_data *buffer)
{
	s32 i = 0;
	s32 len = 0;
	s32 ret = 0;
	s8 data[READER_BUF_SIZ];

	if (!reader || !buffer) {
		debug("reader_communication: para error!!!\n");
		buffer->sw1 = 0x65;
		buffer->sw2 = 0x00;
		return RET_ERR;
	}

	// 数据格式
	memset(data, 0, READER_BUF_SIZ);
	switch (buffer->type) {
		case READER_CONTACTLESS_M1:
		case READER_SETTING:
			data[len++] = buffer->cmd.mf_comm;
			data[len++] = buffer->pa1.mf_flag;
			data[len++] = buffer->pa2.mf_sector;
			data[len++] = buffer->len.mf_len;
			
			for (i=0; i<buffer->len.mf_len; i++) {
				data[len++] = buffer->data[i];
			}
			data[len++] = 0;
			break;
			
		case READER_CONTACT_SAM1:
		case READER_CONTACTLESS_24G:
		case READER_CONTACTLESS_CPU:
			data[len++] = buffer->type;
			data[len++] = 0;
			data[len++] = 0;
			data[len++] = 0;
			data[len++] = buffer->cla;	
			data[len++] = buffer->cmd.ins;	
			data[len++] = buffer->pa1.p1;	
			data[len++] = buffer->pa2.p2;
			
			if (buffer->len.lc == 0) {	
				data[len++] = buffer->le;
			}
			else {
				data[len++] = buffer->len.lc;
				
				for (i=0; i<buffer->len.lc; i++) {
					data[len++] = buffer->data[i];
				}

				if (buffer->le) {
					data[len++] = buffer->le;
				}
				
			}
			data[3]  = len - 4;
			break;

		default:
			buffer->sw1 = 0x65;
			buffer->sw2 = 0x00;
			return RET_ERR_TYPE;

	}

	
	// 工程调试信息
	if (DEBUG_APP_WALL > __DEBUG_APP_O2__) {
		switch (buffer->type) {
			case READER_CONTACTLESS_M1:
			case READER_CONTACT_SAM1:
			case READER_CONTACTLESS_24G:
			case READER_CONTACTLESS_CPU:
				if (buffer->type == READER_CONTACTLESS_24G) {
					debug(">>>[2.4G]===%d:\n", len);
				}
				else if (buffer->type == READER_CONTACTLESS_CPU) {
					debug(">>>[cpu]====%d:\n", len);
				}
				else if (buffer->type == READER_CONTACT_SAM1) {
					debug(">>>[SAM]====%d:\n", len);
				}
				else if (buffer->type == READER_CONTACTLESS_M1) {
					debug(">>>[M1]=====%d:\n", len);
				}
					
				for (i=0; i<len; i++) {
					debug("%02X ", data[i]);
				}
				debug("\n");
				break;

				
		}

	}
 
	switch (buffer->type) {
		case READER_CONTACTLESS_24G:
			break;

		case READER_SETTING:
		case READER_CONTACT_SAM1:
		case READER_CONTACTLESS_CPU:
		case READER_CONTACTLESS_M1:
			ret = app_write(reader->fd[0], data, len);
			if (ret < 0) {
				if (buffer->type != READER_SETTING) {
			    	debug("reader write error\n");   
				}
				buffer->sw1 = 0x65;
				buffer->sw2 = 0x00;
				return RET_ERR_WRITE;
			}

			memset(buffer->data, 0, READER_BUF_SIZ);
			ret = app_read(reader->fd[0], buffer->data, READER_BUF_SIZ);
			if (ret < 0) {
				if (buffer->type != READER_SETTING) {
					debug("reader read error\n");
				}
				buffer->sw1 = 0x65;
				buffer->sw2 = 0x00;
				return RET_ERR_READ;
			}
			break;

		default:
			buffer->sw1 = 0x65;
			buffer->sw2 = 0x00;
			return RET_ERR_TYPE;
	}

	// 工程调试信息
	if (DEBUG_APP_WALL > __DEBUG_APP_O2__) {
		if (buffer->type != READER_SETTING) {
			debug("<<<===%d:\n", ret);
			for (i=0; i<ret; i++) {
				debug("%02X ", buffer->data[i]);
			}
			debug("\n");
		}
	}

	len = 0;
	buffer->cmd.mf_comm   = buffer->data[len++];
	buffer->pa1.mf_flag   = buffer->data[len++];
	buffer->pa2.mf_sector = buffer->data[len++];
	buffer->len.mf_len    = buffer->data[len++];

	for(i=0; i<buffer->len.mf_len; i++) {
		buffer->data[i] = buffer->data[len++];
	}
	buffer->data[i] = buffer->data[len]; 
	
	switch (buffer->type) {
		case READER_CONTACTLESS_24G:
		case READER_CONTACTLESS_CPU:
		case READER_CONTACT_SAM1:
			if (buffer->len.lc > 1) {
				buffer->sw1 = buffer->data[buffer->len.lc-2];
				buffer->sw2 = buffer->data[buffer->len.lc-1];
			} 
			else {
				buffer->sw1 = 0x65;
				buffer->sw2 = 0x00;
			}
			break;
			
		default:
			buffer->sw1 = 0x90;
			buffer->sw2 = 0x00;
			break;
	}

	return RET_OK;  
}




